home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 2: Applications / Linux Cubed Series 2 - Applications.iso / circuits / irsim-ca.2 / irsim-ca / irsim-cap-9.2 / src / ana11 / scrollbar.c < prev    next >
C/C++ Source or Header  |  1993-01-15  |  10KB  |  391 lines

  1. /*
  2.  *     ********************************************************************* 
  3.  *     * Copyright (C) 1988, 1990 Stanford University.                     * 
  4.  *     * Permission to use, copy, modify, and distribute this              * 
  5.  *     * software and its documentation for any purpose and without        * 
  6.  *     * fee is hereby granted, provided that the above copyright          * 
  7.  *     * notice appear in all copies.  Stanford University                 * 
  8.  *     * makes no representations about the suitability of this            * 
  9.  *     * software for any purpose.  It is provided "as is" without         * 
  10.  *     * express or implied warranty.  Export of this software outside     * 
  11.  *     * of the United States of America may require an export license.    * 
  12.  *     *********************************************************************
  13.  */
  14.  
  15. /*
  16.  * Scrollbar manager.
  17.  */
  18. #include "ana.h"
  19. #include "ana_glob.h"
  20. #include "graphics.h"
  21.  
  22. public
  23. #define    SCROLLBARHEIGHT        16
  24. public
  25. #define    ARROW_WIDTH        32
  26.  
  27.  
  28. private    void    StretchLeft(), StretchRight(), MoveBar();
  29. private    void    MoveLeft(), MoveRight();
  30.  
  31.  
  32. public void DrawScrollBar( isExpose )
  33.   int  isExpose;
  34.   {
  35.     static Coord  lastLeft = 0;
  36.     static Coord  lastRight = 0;
  37.  
  38.     if( isExpose or (scrollBox.left > lastLeft) )
  39.     FillAREA( window, 0, scrollBox.top, scrollBox.left, SCROLLBARHEIGHT,
  40.      gcs.white );
  41.     if( isExpose or (scrollBox.right < lastRight) )
  42.     FillAREA( window, scrollBox.right, scrollBox.top,
  43.      XWINDOWSIZE - scrollBox.right, SCROLLBARHEIGHT, gcs.white );
  44.     HLine( window, textBox.left, textBox.right, textBox.top, gcs.black );
  45.     lastLeft = scrollBox.left;
  46.     lastRight = scrollBox.right;
  47.     XCopyArea( display, pix.left_arrows, window, gcs.black, 0, 0, ARROW_WIDTH,
  48.      SCROLLBARHEIGHT, scrollBox.left, scrollBox.top );
  49.     XCopyArea( display, pix.right_arrows, window, gcs.black, 0, 0, ARROW_WIDTH,
  50.      SCROLLBARHEIGHT, scrollBox.right - ARROW_WIDTH, scrollBox.top );
  51.     UpdateScrollBar();
  52.   }
  53.  
  54.  
  55. /*
  56.  * Update and redraw the scrollbar.
  57.  */
  58. public void UpdateScrollBar()
  59.   {
  60.     float  tmp;
  61.  
  62.     if( tims.last == tims.first  )
  63.       {
  64.     barPos.left = traceBox.left;
  65.     barPos.right = traceBox.right;
  66.       }
  67.     else
  68.       {
  69.         TimeType  maxTime;
  70.  
  71.     maxTime = max( tims.last, tims.end );
  72.     tmp = (float)(traceBox.right - traceBox.left) / (maxTime-tims.first);
  73.     barPos.left = traceBox.left + round( tmp * (tims.start-tims.first) );
  74.     barPos.right = barPos.left + round( tmp * tims.steps );
  75.     if( barPos.right - barPos.left < 3 )
  76.       {
  77.         if( barPos.left + 3 > traceBox.right )
  78.         barPos.left = barPos.right - 3;
  79.         else
  80.         barPos.right = barPos.left + 3;
  81.       }
  82.       }
  83.     FillAREA( window, traceBox.left + 1, scrollBox.top + 1,
  84.       traceBox.right - traceBox.left - 1, SCROLLBARHEIGHT - 2, gcs.gray );
  85.     VLine( window, traceBox.left, scrollBox.bot, scrollBox.top, gcs.black );
  86.     VLine( window, traceBox.right, scrollBox.bot, scrollBox.top, gcs.black );
  87.  
  88.     FillBox( window, barPos, gcs.white );
  89.     OutlineBox( window, barPos, gcs.black );
  90.   }
  91.  
  92.  
  93.  
  94. /*
  95.  * Handle button clicks within the scrollbar.
  96.  */
  97. public void DoScrollBar( ev )
  98.   XButtonEvent  *ev;
  99.   {
  100.     TimeType  oldStart, oldSteps;
  101.  
  102.     if( (ev->x < scrollBox.left) or (ev->x > scrollBox.right) )
  103.     return;
  104.  
  105.     if( ev->x < scrollBox.left + (ARROW_WIDTH / 2 - 1) )
  106.     MoveLeft( 2 );
  107.     else if( ev->x < traceBox.left )
  108.     MoveLeft( 1 );
  109.     else if( ev->x <= traceBox.right )
  110.       {
  111.     oldStart = tims.start;
  112.     oldSteps = tims.steps;
  113.  
  114.     switch( ev->button & (Button1 | Button2 | Button3) )
  115.       {
  116.         case Button1 :
  117.         StretchLeft( ev->x );
  118.         break;
  119.         case Button2 :
  120.         MoveBar( ev->x );
  121.         break;
  122.         case Button3 :
  123.         StretchRight( ev->x );
  124.         break;
  125.       }
  126.     UpdateScrollBar();
  127.     if( (oldStart != tims.start) or (oldSteps != tims.steps) )
  128.       {
  129.         DrawTraces( tims.start, tims.end );
  130.         RedrawTimes();
  131.       }
  132.       }
  133.     else if( ev->x < scrollBox.right - (ARROW_WIDTH / 2 - 1) )
  134.       {
  135.     MoveRight( 1 );
  136.       }
  137.     else            /* ( x < scrol.right ) */
  138.     MoveRight( 2 );
  139.   }
  140.  
  141.  
  142. /*
  143.  * Stretch the scroll bar to the left, up to the current right side.
  144.  */
  145. private void StretchLeft( x )
  146.   Coord  x;
  147.   {
  148.     Coord     xmax;
  149.     XEvent    ev;
  150.     float     tmp;
  151.     TimeType  maxTime, ti;
  152.     BBox      b;
  153.  
  154.     maxTime = max( tims.last, tims.end );
  155.     if( maxTime <= tims.first )
  156.     return;
  157.  
  158.     tmp = (float)(maxTime - tims.first) / (traceBox.right - traceBox.left);
  159.     xmax = barPos.right - max( 3, round( 10.0 / tmp ) );
  160.  
  161.     b.top = barPos.top + 1;
  162.     b.bot = barPos.bot - 1;
  163.     b.left = barPos.left;
  164.     b.right = barPos.right - 1;
  165.     FillBox( window, b, gcs.gray );
  166.     b.left = min( x, xmax );
  167.     FillBox( window, b, gcs.white );
  168.  
  169.     GrabMouse( window, ButtonPressMask | ButtonMotionMask | ButtonReleaseMask,
  170.      None );
  171.  
  172.     UpdateTimes( tims.start, tims.end );    /* initialize it */
  173.  
  174.     do
  175.       {
  176.     XNextEvent( display, &ev ); 
  177.     if( ev.type == MotionNotify )
  178.         x = ev.xmotion.x;
  179.     else if( ev.type == ButtonRelease )
  180.         x = ev.xbutton.x;
  181.     else
  182.         continue;
  183.  
  184.     FillBox( window, b, gcs.gray );
  185.     if( x < traceBox.left )
  186.         b.left = traceBox.left;
  187.     else if( x > xmax )
  188.         b.left = xmax;
  189.     else
  190.         b.left = x;
  191.     FillBox( window, b, gcs.white );
  192.     ti = tims.first + round( (b.left - traceBox.left) * tmp );
  193.     UpdateTimes( ti, tims.end );
  194.       }
  195.     while( ev.type != ButtonRelease );
  196.  
  197.     XUngrabPointer( display, CurrentTime );
  198.     XFlush( display );
  199.  
  200.     barPos.left = b.left;
  201.     tims.start = tims.first + round( (b.left - traceBox.left) * tmp );
  202.     tims.steps = tims.end - tims.start;
  203.   }
  204.  
  205.  
  206.  
  207. /*
  208.  * Stretch the scroll bar to the right, up to the current left side.
  209.  */
  210. private void StretchRight( x )
  211.   Coord  x;
  212.   {
  213.     Coord     xmin;
  214.     XEvent    ev;
  215.     float     tmp;
  216.     TimeType  maxTime, ti;
  217.     BBox      b;
  218.  
  219.     maxTime = max( tims.last, tims.end );
  220.     if( maxTime <= tims.first )
  221.     return;
  222.  
  223.     tmp = (float)(maxTime - tims.first) / (traceBox.right - traceBox.left);
  224.     xmin = barPos.left + max( 3, round( 10.0/tmp ) );
  225.  
  226.     b.top = barPos.top + 1;
  227.     b.bot = barPos.bot - 1;
  228.     b.left = barPos.left + 1;
  229.     b.right = barPos.right;
  230.     FillBox( window, b, gcs.gray );
  231.     b.right = max( x, xmin );
  232.     FillBox( window, b, gcs.white );
  233.  
  234.     GrabMouse( window, ButtonPressMask | ButtonMotionMask | ButtonReleaseMask,
  235.      None );
  236.  
  237.     UpdateTimes( tims.start, tims.end );    /* initialize it */
  238.  
  239.     do
  240.       {
  241.     XNextEvent( display, &ev );
  242.     if( ev.type == MotionNotify )
  243.         x = ev.xmotion.x;
  244.     else if( ev.type == ButtonRelease )
  245.         x = ev.xbutton.x;
  246.     else
  247.         continue;
  248.  
  249.     FillBox( window, b, gcs.gray );
  250.     if( x < xmin )
  251.         b.right = xmin;
  252.     else if( x > traceBox.right )
  253.         b.right = traceBox.right;
  254.     else
  255.         b.right = x;
  256.     FillBox( window, b, gcs.white );
  257.     ti = tims.first + round( (b.right - traceBox.left) * tmp );
  258.     UpdateTimes( tims.start, ti );
  259.       }
  260.     while( ev.type != ButtonRelease );
  261.  
  262.     XUngrabPointer( display, CurrentTime );
  263.     XFlush( display );
  264.  
  265.     barPos.right = b.right;
  266.     tims.end = tims.first + round( (b.right - traceBox.left) * tmp );
  267.     tims.steps = tims.end - tims.start;
  268.   }
  269.  
  270.  
  271. /*
  272.  * Move the scrollbar left or right, always within the scrollbar bounds.
  273.  */
  274. private void MoveBar( x )
  275.   Coord     x;
  276.   {
  277.     XEvent    ev;
  278.     Coord     width, handle;
  279.     Coord     top, height;
  280.     float     tmp;
  281.     TimeType  maxTime, t1, t2;
  282.  
  283.     maxTime = max( tims.last, tims.end );
  284.     if( maxTime <= tims.first )
  285.     return;
  286.  
  287.     tmp = (float)(maxTime - tims.first) / (traceBox.right - traceBox.left);
  288.  
  289.     top = barPos.top + 1;
  290.     height = barPos.bot - barPos.top - 1;    /* bot - top - 1 - 1 + 1 */
  291.     width = barPos.right - barPos.left + 1;
  292.  
  293.     if( x >= barPos.left and x <= barPos.right )
  294.     handle = x - barPos.left;
  295.     else if( (x > barPos.right) and (x + width - 1 > traceBox.right) )
  296.     handle = x + width - traceBox.right - 1;
  297.     else
  298.     handle = 0;
  299.  
  300.     FillAREA( window, barPos.left, top, width, height, gcs.gray );
  301.     FillAREA( window, x - handle, top, width, height, gcs.white );
  302.  
  303.     GrabMouse( window, ButtonPressMask | ButtonMotionMask | ButtonReleaseMask,
  304.      None );
  305.  
  306.     UpdateTimes( tims.start, tims.end );    /* initialize it */
  307.  
  308.     do
  309.       {
  310.     XNextEvent( display, &ev );
  311.     if( ev.type != MotionNotify and ev.type != ButtonRelease )
  312.         continue;
  313.  
  314.     FillAREA( window, x - handle, top, width, height, gcs.gray );
  315.     x = (ev.type == MotionNotify) ? ev.xmotion.x : ev.xbutton.x;
  316.     if( x - handle + width - 1 > traceBox.right )
  317.       {
  318.         if( x > traceBox.right )
  319.         x = traceBox.right;
  320.         handle = x - (traceBox.right - width + 1);
  321.       }
  322.     else if( x - handle < traceBox.left )
  323.       {
  324.         if( x < traceBox.left )
  325.         x = traceBox.left;
  326.         handle = x - traceBox.left;
  327.       }
  328.     FillAREA( window, x - handle, top, width, height, gcs.white );
  329.     t1 = round( (x - handle - traceBox.left) * tmp ) + tims.first;
  330.     t2 = t1 + tims.steps;
  331.     UpdateTimes( t1, t2 );
  332.       }
  333.     while( ev.type != ButtonRelease );
  334.  
  335.     XUngrabPointer( display, CurrentTime );
  336.     XFlush( display );
  337.  
  338.     barPos.left = x - handle;
  339.     barPos.right = x - handle + width - 1;
  340.  
  341.     tims.start = round( (barPos.left - traceBox.left) * tmp ) + tims.first;
  342.     tims.end = tims.start + tims.steps;
  343.   }
  344.  
  345.  
  346. /*
  347.  * Scroll left by 'hpages' half-pages.
  348.  */
  349. private void MoveLeft( hpages )
  350.   int  hpages;
  351.   {
  352.     TimeType  start;
  353.  
  354.     start = tims.start - (hpages * tims.steps) / 2;
  355.  
  356.     if( start < tims.first )
  357.     start = tims.first;
  358.  
  359.     if( start == tims.start )
  360.     return;
  361.  
  362.     tims.start = start;
  363.     tims.end = start + tims.steps;
  364.  
  365.     RedrawTimes();
  366.     UpdateScrollBar();
  367.     DrawTraces( start, tims.end );
  368.   }
  369.  
  370.  
  371. /*
  372.  * Scroll right by 'hpages' half-pages.
  373.  */
  374. private void MoveRight( hpages )
  375.   int  hpages;
  376.   {
  377.     TimeType  start;
  378.  
  379.     start = tims.start + (hpages * tims.steps) / 2;
  380.  
  381.     if( (start >= tims.last) or (start == tims.start) or
  382.       (start + tims.steps >= max_time ) )
  383.     return;
  384.  
  385.     tims.start = start;
  386.     tims.end = start + tims.steps;
  387.     RedrawTimes();
  388.     UpdateScrollBar();
  389.     DrawTraces( start, tims.end );
  390.   }
  391.